﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Common;
using NBusiness.Query;
using NBusiness.Data.Providers.SqlServer.Query;
using System.Data.SqlClient;
using System.Data;

namespace NBusiness.Data.Providers.SqlServer
{
    class SqlServerDatabaseProvider : IDatabaseProvider
    {
        #region IDatabaseProvider Members

        public void Execute(IQuery query) { }

        public void Execute(IQuery query, string connectionString)
        {
            using (SqlConnection cn = new SqlConnection(connectionString))
            {
                SqlTransaction trans = cn.BeginTransaction();
                try
                {
                    StringBuilder sql = new StringBuilder();
                    List<IParameterValue> parameters = new List<IParameterValue>();
                    foreach (IStatement statement in query.Statements)
                    {
                        if (statement is IGo)
                        {
                            using (SqlCommand cmd = cn.CreateCommand())
                            {
                                cmd.Transaction = trans;
                                cmd.CommandText = sql.ToString();
                                cmd.CommandType = (statement is IProcedure ? CommandType.StoredProcedure : CommandType.Text);
                                foreach (IParameterValue value in parameters)
                                {
                                    System.Data.SqlClient.SqlParameter p = cmd.Parameters.AddWithValue(value.Name, value.Value);
                                    p.Direction = (ParameterDirection)value.Direction;
                                }
                            }
                            sql = new StringBuilder();
                        }
                        else
                        {
                            IHaveParameters hp = statement as IHaveParameters;
                            if(hp!=null)
                                parameters.AddRange(hp.Parameters);
                            sql.AppendLine(statement.ToSql());
                        }
                    }
                    trans.Commit();
                }
                catch
                {
                    trans.Rollback();
                    throw;
                }
            }
        }

        #endregion

        #region IDatabaseProvider Members

        public IQuery Query()
        {
            return new SqlQuery();
        }

        public ITable Table(string name)
        {
            return new SqlTable(name);
        }

        #endregion
    }
}
